using System.Collections;
using Microsoft.EntityFrameworkCore;
using net_work.Common.Request;
using net_work.Common.Result;
using net_work.Data.Entity;
using net_work.IRepository;
using Newtonsoft.Json;

namespace net_work.Repository;

public class Repository<T> : IRepository<T> where T : BaseEntity
{
    private readonly DbContext _context;
    private readonly DbSet<T> _dbSet;

    protected Repository(DbContext context)
    {
        _context = context;
        _dbSet = _context.Set<T>();
    }

    public async Task<IEnumerable<T>> GetAllAsync()
    {
        return await _dbSet.ToListAsync();
    }

    public async Task<PagedResult<T>> GetPagedAsync(PagedRequest request)
    {
        // 确保分页参数合法
        if (request.PageNumber < 1)
        {
            request.PageNumber = 1;
        }

        // 获取实体的属性名称列表
        var entityProperties = typeof(T).GetProperties().Select(p => p.Name).ToHashSet();

        // 检查过滤条件中的属性名称是否合法
        if (request.Filters != null)
        {
            foreach (var filter in request.Filters)
            {
                filter.PropertyName = ConvertToPascalCase(filter.PropertyName);

                if (!entityProperties.Contains(filter.PropertyName))
                {
                    throw new ArgumentException($"无效的属性名: {filter.PropertyName}");
                }

                // 校验枚举是否合法
                if (!Enum.IsDefined(typeof(FilterOperator), filter.Operator))
                {
                    throw new ArgumentException($"无效的操作符: {filter.Operator}");
                }
            }
        }

        // 获取查询源
        var query = _context.Set<T>().AsQueryable();

        // 动态筛选条件
        if (request.Filters != null)
        {
            foreach (var filter in request.Filters)
            {
                var propertyName = filter.PropertyName;
                var value = filter.Value;

                // 检查是否是枚举类型
                if (typeof(T).GetProperty(propertyName)?.PropertyType.IsEnum == true)
                {
                    // 将字符串值转换为枚举
                    value = Enum.Parse(
                        typeof(T).GetProperty(propertyName)?.PropertyType ?? throw new InvalidOperationException(),
                        value.ToString() ?? throw new InvalidOperationException());
                }

                // 自动处理操作符 In 的数据
                if (filter.Operator == FilterOperator.In)
                {
                    if (value is string strValue)
                    {
                        // 如果 value 是 JSON 格式的字符串，解析为 List<object>
                        value = JsonConvert.DeserializeObject<List<object>>(strValue);
                    }
                    else if (value is IEnumerable enumerableValue)
                    {
                        // 转换普通集合
                        value = enumerableValue.Cast<object>().ToList();
                    }
                    else
                    {
                        throw new ArgumentException($"操作符 In 的值必须是一个集合类型或 JSON 字符串，但接收到 {value?.GetType().Name}。");
                    }
                }

                query = filter.Operator switch
                {
                    FilterOperator.Equals => query.Where(e =>
                        EF.Property<object>(e, propertyName).Equals(value)),
                    FilterOperator.NotEquals => query.Where(e =>
                        !EF.Property<object>(e, propertyName).Equals(value)),
                    FilterOperator.GreaterThan => query.Where(e =>
                        Convert.ToDouble(EF.Property<object>(e, propertyName)) > Convert.ToDouble(value)),
                    FilterOperator.LessThan => query.Where(e =>
                        Convert.ToDouble(EF.Property<object>(e, propertyName)) < Convert.ToDouble(value)),
                    FilterOperator.Like => query.Where(e =>
                        EF.Property<string>(e, propertyName).Contains(value.ToString() ?? string.Empty)),
                    FilterOperator.StartsWith => query.Where(e =>
                        EF.Property<string>(e, propertyName).StartsWith(value.ToString() ?? string.Empty)),
                    FilterOperator.EndsWith => query.Where(e =>
                        EF.Property<string>(e, propertyName).EndsWith(value.ToString() ?? string.Empty)),
                    FilterOperator.In => query.Where(e =>
                        ((IEnumerable<object>)value).Contains(EF.Property<object>(e, propertyName))),
                    _ => throw new ArgumentException($"不支持的操作符: {filter.Operator}")
                };
            }
        }

        // 获取总记录数
        var totalRecords = await query.CountAsync();

        // 检查是否为 Unlimited 模式
        if (request.PageSize == PageSizeEnum.Unlimited)
        {
            // 获取所有数据
            var data = await query
                .OrderBy(e => EF.Property<object>(e, "Id")) // 按主键递增排序
                .ToListAsync();

            // 返回不分页的结果
            return new PagedResult<T>
            {
                TotalRecords = totalRecords,
                TotalPages = 1, // 只有一页
                PageNumber = 1, // 默认第一页
                PageSize = totalRecords, // 全部数据大小
                Data = data
            };
        }

        // 普通分页模式
        var totalPages = (int)Math.Ceiling(totalRecords / (double)(int)request.PageSize);
        if (request.PageNumber > totalPages && totalPages > 0)
        {
            request.PageNumber = totalPages; // 自动调整到最后一页
        }

        var dataPaged = await query
            .OrderBy(e => EF.Property<object>(e, "Id")) // 按主键递增排序
            .Skip((request.PageNumber - 1) * (int)request.PageSize)
            .Take((int)request.PageSize)
            .ToListAsync();

        // 返回分页结果
        return new PagedResult<T>
        {
            TotalRecords = totalRecords,
            TotalPages = totalPages,
            PageNumber = request.PageNumber,
            PageSize = (int)request.PageSize,
            Data = dataPaged
        };
    }

    public async Task<PagedResult<TB>> GetPagedQueryResultAsync<TB>(IQueryable<TB> query, PagedRequest request)
    {
        // 确保分页参数合法
        if (request.PageNumber < 1)
        {
            request.PageNumber = 1;
        }

        // 获取实体的属性名称列表
        var entityProperties = typeof(TB).GetProperties().Select(p => p.Name).ToHashSet();

        // 检查过滤条件中的属性名称是否合法
        if (request.Filters != null)
        {
            foreach (var filter in request.Filters)
            {
                filter.PropertyName = ConvertToPascalCase(filter.PropertyName);

                if (!entityProperties.Contains(filter.PropertyName))
                {
                    throw new ArgumentException($"无效的属性名: {filter.PropertyName}");
                }

                // 校验枚举是否合法
                if (!Enum.IsDefined(typeof(FilterOperator), filter.Operator))
                {
                    throw new ArgumentException($"无效的操作符: {filter.Operator}");
                }
            }
        }

        // 动态筛选条件
        if (request.Filters != null)
        {
            foreach (var filter in request.Filters)
            {
                var propertyName = filter.PropertyName;
                var value = filter.Value;

                // 检查是否是枚举类型
                if (typeof(TB).GetProperty(propertyName)?.PropertyType.IsEnum == true)
                {
                    // 将字符串值转换为枚举
                    value = Enum.Parse(
                        typeof(TB).GetProperty(propertyName)?.PropertyType ?? throw new InvalidOperationException(),
                        value.ToString() ?? throw new InvalidOperationException());
                }

                // 自动处理操作符 In 的数据
                if (filter.Operator == FilterOperator.In)
                {
                    if (value is string strValue)
                    {
                        // 如果 value 是 JSON 格式的字符串，解析为 List<object>
                        value = JsonConvert.DeserializeObject<List<long>>(strValue);
                    }
                    else if (value is IEnumerable enumerableValue)
                    {
                        // 转换普通集合
                        value = enumerableValue.Cast<object>().ToList();
                    }
                    else
                    {
                        throw new ArgumentException($"操作符 In 的值必须是一个集合类型或 JSON 字符串，但接收到 {value?.GetType().Name}。");
                    }
                }

                query = filter.Operator switch
                {
                    FilterOperator.Equals => query.Where(e =>
                        EF.Property<object>(e, propertyName).Equals(value)),
                    FilterOperator.NotEquals => query.Where(e =>
                        !EF.Property<object>(e, propertyName).Equals(value)),
                    FilterOperator.GreaterThan => query.Where(e =>
                        Convert.ToDouble(EF.Property<object>(e, propertyName)) > Convert.ToDouble(value)),
                    FilterOperator.LessThan => query.Where(e =>
                        Convert.ToDouble(EF.Property<object>(e, propertyName)) < Convert.ToDouble(value)),
                    FilterOperator.Like => query.Where(e =>
                        EF.Property<string>(e, propertyName).Contains(value.ToString() ?? string.Empty)),
                    FilterOperator.StartsWith => query.Where(e =>
                        EF.Property<string>(e, propertyName).StartsWith(value.ToString() ?? string.Empty)),
                    FilterOperator.EndsWith => query.Where(e =>
                        EF.Property<string>(e, propertyName).EndsWith(value.ToString() ?? string.Empty)),
                    FilterOperator.In => query.Where(e =>
                        ((IEnumerable<long>)value).Contains(EF.Property<long>(e, propertyName))),
                    _ => throw new ArgumentException($"不支持的操作符: {filter.Operator}")
                };
            }
        }

        // 获取总记录数
        var totalRecords = await query.CountAsync();

        // 检查是否为 Unlimited 模式
        if (request.PageSize == PageSizeEnum.Unlimited)
        {
            // 获取所有数据
            var data = await query
                .OrderBy(e => EF.Property<object>(e, "Id")) // 按主键递增排序
                .ToListAsync();

            // 返回不分页的结果
            return new PagedResult<TB>
            {
                TotalRecords = totalRecords,
                TotalPages = 1, // 只有一页
                PageNumber = 1, // 默认第一页
                PageSize = totalRecords, // 全部数据大小
                Data = data
            };
        }

        // 普通分页模式
        var totalPages = (int)Math.Ceiling(totalRecords / (double)(int)request.PageSize);
        if (request.PageNumber > totalPages && totalPages > 0)
        {
            request.PageNumber = totalPages; // 自动调整到最后一页
        }

        var dataPaged = await query
            .OrderBy(e => EF.Property<object>(e, "Id")) // 按主键递增排序
            .Skip((request.PageNumber - 1) * (int)request.PageSize)
            .Take((int)request.PageSize)
            .ToListAsync();

        // 返回分页结果
        return new PagedResult<TB>
        {
            TotalRecords = totalRecords,
            TotalPages = totalPages,
            PageNumber = request.PageNumber,
            PageSize = (int)request.PageSize,
            Data = dataPaged
        };
    }


    public async Task<T?> GetByIdAsync(long id)
    {
        return await _dbSet.FindAsync(id);
    }

    public async Task<bool> DeleteByIdAsync(long id)
    {
        var entity = await _dbSet.FindAsync(id);
        if (entity == null || entity.DelFlag == '2')
        {
            return false;
        }

        entity.DelFlag = '0';
        _dbSet.Update(entity);
        await _context.SaveChangesAsync();
        return true;
    }

    public async Task<bool> DeleteByIdsAsync(List<long> ids)
    {
        var entities = await _dbSet.Where(x => ids.Contains(x.Id)).ToListAsync();
        foreach (var entity in entities)
        {
            entity.DelFlag = '2';
            _dbSet.Update(entity);
        }

        await _context.SaveChangesAsync();
        return true;
    }

    private static string ConvertToPascalCase(string camelCase)
    {
        if (string.IsNullOrEmpty(camelCase))
        {
            throw new ArgumentException($"无效的属性名: {camelCase}");
        }

        if (!char.IsLower(camelCase[0]))
        {
            return camelCase;
        }

        return char.ToUpper(camelCase[0]) + camelCase[1..];
    }

    public async Task<bool> ValidateByList(List<long> list)
    {
        if (list.Count == 0)
        {
            return false;
        }

        // 去重，避免查询重复的 ID
        var distinctList = list.Distinct().ToList();

        // 执行批量查询，获取在数据库中的实体
        var entities = await _dbSet.Where(x => distinctList.Contains(x.Id)).ToListAsync();

        // 如果返回的实体数量和去重后的列表数量一致，则说明所有 ID 都有效
        return entities.Count == distinctList.Count;
    }
}